﻿using Iesi.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
using OpenCvSharp;
using OpenCvSharp.Flann;
using OpenVinoSharp;
using SharpCompress;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Eventing.Reader;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml.Linq;
using System.Xml.Serialization;
using 摸鱼;
using static OpenCvSharp.LineIterator;
using static 摸鱼._数据库;
using static 摸鱼._数据库._方案;
using static 摸鱼._数据库._方案._步骤;
using static 摸鱼.全局类;
using static 摸鱼.核心;
using static 摸鱼.键鼠.钩子;
using Brushes = System.Windows.Media.Brushes;
using Color = System.Windows.Media.Color;
using Control = System.Windows.Forms.Control;
using Debug = System.Diagnostics.Debug;
using Image = System.Windows.Controls.Image;
using JsonIgnoreAttribute = Newtonsoft.Json.JsonIgnoreAttribute;
using JsonSerializer = Newtonsoft.Json.JsonSerializer;
using Rectangle = System.Drawing.Rectangle;
using RichTextBox = System.Windows.Controls.RichTextBox;
using TreeView = System.Windows.Controls.TreeView;

namespace 摸鱼
{
    public static class 全局类
    {
        public static _数据库 数据库;
        public static int 屏幕宽度, 屏幕高度;
        public static bool 按下结束键;
        public static bool 初始化完成;
        public static Dictionary<string, string> 方法修改列表 = new();
        public static Random random = new Random((int)时间戳);
        public static _列表数据<_方法> 方法列表数据 = new();
        public static _列表数据<_步骤> 步骤列表数据 = new();
        public static _列表数据<_方案> 方案列表数据 = new();
        [SkipLocalsInit]
        public static double 时间戳 => Stopwatch.GetTimestamp() * 0.0001;
        public static readonly JsonSerializer serializer = new JsonSerializer()
        {
            PreserveReferencesHandling = PreserveReferencesHandling.Objects,
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
            NullValueHandling = NullValueHandling.Ignore
        };



        public class _列表数据<T> where T : class
        {
            private Dictionary<T, TreeViewItem> 控件 = new();
            private Dictionary<TreeViewItem, T> 数据 = new();
            public TreeViewItem? this[T item]
            {
                get
                {
                    控件.TryGetValue(item, out var rus);
                    return rus;
                }
                set
                {
                    控件[item] = value;
                    数据[value] = item;
                }
            }
            public T? this[TreeViewItem item]
            {
                get
                {
                    数据.TryGetValue(item, out var rus);
                    return rus;
                }
                set
                {
                    控件[value] = item;
                    数据[item] = value;
                }
            }
            public void Clear()
            {
                控件.Clear();
                数据.Clear();
            }
            public bool TryGetValue(T key, [MaybeNullWhen(false)] out TreeViewItem value)
            {
                return 控件.TryGetValue(key, out value);
            }
            public bool TryGetValue(TreeViewItem key, [MaybeNullWhen(false)] out T value)
            {
                return 数据.TryGetValue(key, out value);
            }
            public void Remove(_方法 方法)
            {
                _方法 父方法 = 方法.父.FirstOrDefault();
                ItemsControl 父Control;
                if (父方法 == default)
                {
                    父Control = MainWindow.This.方法列表;
                    数据库.当前步骤.方法.Remove(方法);
                }
                else
                {
                    父Control = 控件[父方法 as T];
                    父方法.子.Remove(方法);
                }
                var 控件item = 控件[方法 as T];
                父Control.Items.Remove(控件item);
                数据.Remove(控件item);
                控件.Remove(方法 as T);
                方法.Dispose();
            }
            public void Remove(_方案 方案, bool 清空变量原数据)
            {
                _方案 父方案 = 方案.父.FirstOrDefault();
                ItemsControl 父Control;
                if (父方案 == default)
                {
                    父Control = MainWindow.This.方案列表;
                    数据库.方案.Remove(方案);
                }
                else
                {
                    父Control = 控件[父方案 as T];
                    父方案.子.Remove(方案);
                }
                var 控件item = 控件[方案 as T];
                父Control.Items.Remove(控件item);
                数据.Remove(控件item);
                控件.Remove(方案 as T);
                方案.Dispose(清空变量原数据);
            }
            public void Remove(_步骤 步骤, bool 清空变量原数据)
            {
                ItemsControl 父Control;
                数据库.当前方案.步骤.Remove(步骤);
                var 控件item = 控件[步骤 as T];
                MainWindow.This.步骤列表.Items.Remove(控件item);
                数据.Remove(控件item);
                控件.Remove(步骤 as T);
                步骤.Dispose(清空变量原数据);

                int index = 1;
                foreach (TreeViewItem item in MainWindow.This.步骤列表.Items)
                {
                    string bzName = 数据库.当前方案.步骤[index - 1].名字;
                    if (bzName != null)
                        item.Header = bzName + index++;
                    else
                        item.Header = "步骤" + index++;
                }
                //for (int i = 0; i < 数据库.当前方案.步骤.Count; i++)
                //    ((TreeViewItem)MainWindow.This.步骤列表.Items[i]).Header = "步骤" + (i + 1);
            }
            public void Add(_方法 key, _方法 value, int index = -1)
            {
                if (数据库?.当前步骤 == null)
                    return;
                List<_方法> 方法 = 数据库.当前步骤.方法;

                TreeViewItem 节点;
                TreeView 方法列表 = (TreeView)MainWindow.This.方法列表;
                if (key == null)
                {
                    方法.Add(value);
                    value.Set节点数据(方法.Count - 1, null, out 节点);
                    方法列表.Items.Add(节点);
                }
                else
                {
                    if (index > -1)
                    {
                        var key父 = key.父.FirstOrDefault();
                        if (key父 != null)
                        {
                            key父.子.Insert(index, value);
                            value.父.Add(key父);
                            value.Set节点数据(index, key, out 节点);
                            方法列表数据[key父].Items.Insert(index, 节点);
                        }
                        else
                        {
                            数据库.当前步骤.方法.Insert(index, value);
                            value.Set节点数据(index, key, out 节点);
                            方法列表.Items?.Insert(index, 节点);
                        }
                    }
                    else
                    {
                        key.子.Add(value);
                        value.父.Add(key);
                        value.Set节点数据(key.子.Count - 1, key, out 节点);
                        ((TreeViewItem)方法列表?.SelectedItem)?.Items.Add(节点);
                    }
                }
                方法列表数据[value] = 节点;
                UI刷新.方法列表Add(节点, value.子);
                UI刷新.检查方法参数(value);
                节点.IsSelected = true;
            }
            public void Add(_方案 key, _方案 value, int index = -1)
            {
                TreeView 方案列表 = MainWindow.This.方案列表;
                TreeViewItem 节点;
                if (方案列表.SelectedItem == null)
                {
                    数据库.方案.Add(value);
                    value.Set节点数据(数据库.方案.Count - 1, null, out 节点);
                    方案列表.Items.Add(节点);
                }
                else
                {
                    if (index > -1)
                    {
                        var key父 = key.父.FirstOrDefault();
                        if (key父 != null)
                        {
                            key父.子.Insert(index, value);
                            value.父.Add(key父);
                            value.Set节点数据(index, key, out 节点);
                            方案列表数据[key父].Items.Insert(index, 节点);
                        }
                        else
                        {
                            数据库.方案.Insert(index, value);
                            value.Set节点数据(index, key, out 节点);
                            方案列表.Items?.Insert(index, 节点);
                        }
                    }
                    else
                    {
                        key.子.Add(value);
                        value.父.Add(key);
                        value.Set节点数据(key.子.Count - 1, key, out 节点);
                        ((TreeViewItem)方案列表?.SelectedItem)?.Items.Add(节点);
                    }
                }
                数据库.当前方案 = value;
                方案列表数据[value] = 节点;
                UI刷新.方案列表Add(节点, value.子);
                节点.IsSelected = true;
            }
            public bool Add(_步骤 value, int index = -1)
            {
                if (方案为空() || 数据库.当前方案 == null)
                    return false;

                TreeViewItem 节点;
                if (index > -1)
                {
                    数据库.当前方案.步骤.Insert(index, value);
                    value.Set节点数据(index, null, out 节点);
                    MainWindow.This.步骤列表.Items.Insert(index, 节点);
                    步骤列表数据[value] = 节点;
                }
                else
                {
                    数据库.当前方案.步骤.Add(value);
                    value.Set节点数据(数据库.当前方案.步骤.Count - 1, null, out 节点);
                    MainWindow.This.步骤列表.Items.Add(节点);
                    步骤列表数据[value] = 节点;
                }
                index = 1;
                foreach (TreeViewItem item in MainWindow.This.步骤列表.Items)
                {
                    string bzName = 数据库.当前方案.步骤[index - 1].名字;
                    if (bzName != null)
                        item.Header = bzName + index++;
                    else
                        item.Header = "步骤" + index++;
                }
                节点.IsSelected = true;
                return true;
            }
            public void Insert(_方法 key, _方法 value)
            {
                int index = -1;
                if (key != null)
                {
                    _方法 key父 = key.父.FirstOrDefault();
                    if (key父 != null)
                        index = key父.子.LastIndexOf(key);
                    else
                        index = 数据库.当前步骤.方法.LastIndexOf(key);
                }
                Add(key, value, index);
            }

            public void Insert(_方案 key, _方案 value)
            {
                int index = -1;
                if (key != null)
                {
                    _方案 key父 = key.父.FirstOrDefault();
                    if (key父 != null)
                        index = key父.子.IndexOf(key);
                    else
                        index = 数据库.方案.IndexOf(key);
                }
                Add(key, value, index);
            }
            public void Insert(_步骤 value)
            {
                int index = -1;
                if (数据库.当前步骤 != null)
                    index = 数据库.当前方案.步骤.IndexOf(数据库.当前步骤);
                Add(value, index);
            }

            public void Replace(_方法 key, _方法 value)
            {
                if (数据库?.当前步骤 == null)
                    return;
                List<_方法> 方法 = 数据库.当前步骤.方法;

                TreeViewItem 节点;
                TreeView 方法列表 = (TreeView)MainWindow.This.方法列表;
                if (key == null)
                {
                    方法.Add(value);
                    value.Set节点数据(方法.Count - 1, null, out 节点);
                    方法列表.Items.Add(节点);
                }
                else
                {
                    int index = -1;
                    _方法 key父 = key.父.FirstOrDefault();
                    if (key父 != null)
                        index = key父.子.LastIndexOf(key);
                    else
                        index = 数据库.当前步骤.方法.LastIndexOf(key);

                    if (index > -1)
                    {
                        key父 = key.父.FirstOrDefault();
                        if (key父 != null)
                        {
                            var 原方法 = key父.子[index];
                            if (原方法.子.Count != 0)
                                value.子 = 原方法.子.Select(x => new _方法(x, value)).ToList();
                            value.父 = new(原方法.父);
                            原方法.Dispose();
                            key父.子[index] = value;
                            value.父.Add(key父);
                            value.Set节点数据(index, key, out 节点);
                            方法列表数据[key父].Items[index] = 节点;
                        }
                        else
                        {
                            var 原方法 = 数据库.当前步骤.方法[index];
                            if (原方法.子.Count != 0)
                                value.子 = 原方法.子.Select(x => new _方法(x, value)).ToList();
                            value.父 = new(原方法.父);
                            原方法.Dispose();
                            数据库.当前步骤.方法[index] = value;
                            value.Set节点数据(index, key, out 节点);
                            方法列表.Items[index] = 节点;
                        }
                    }
                    else
                    {
                        key.子.Add(value);
                        value.父.Add(key);
                        value.Set节点数据(key.子.Count - 1, key, out 节点);
                        ((TreeViewItem)方法列表?.SelectedItem)?.Items.Add(节点);
                    }
                }
                方法列表数据[value] = 节点;
                UI刷新.方法列表Add(节点, value.子);
                UI刷新.检查方法参数(value);
                节点.IsSelected = true;
            }
            public void Replace(_方案 key, _方案 value)
            {
                TreeView 方案列表 = MainWindow.This.方案列表;
                TreeViewItem 节点;
                if (key == null)
                {
                    数据库.方案.Add(value);
                    value.Set节点数据(数据库.方案.Count - 1, null, out 节点);
                    方案列表.Items.Add(节点);
                }
                else
                {
                    int index = -1;
                    _方案 key父 = key.父.FirstOrDefault();
                    if (key父 != null)
                        index = key父.子.IndexOf(key);
                    else
                        index = 数据库.方案.IndexOf(key);

                    if (index > -1)
                    {
                        key父 = key.父.FirstOrDefault();
                        if (key父 != null)
                        {
                            var 原方案 = key父.子[index];
                            if (原方案.子.Count != 0)
                            {
                                value.子 = 原方案.子.Select(x => new _方案(x, false, value)).ToList();
                                原方案.Dispose(false);
                            }
                            else
                                原方案.Dispose(true);
                            value.父 = new(原方案.父);

                            key父.子[index] = value;
                            value.父.Add(key父);
                            value.Set节点数据(index, key, out 节点);
                            方案列表数据[key父].Items[index] = 节点;
                        }
                        else
                        {
                            var 原方案 = 数据库.方案[index];
                            if (原方案.子.Count != 0)
                            {
                                value.子 = 原方案.子.Select(x => new _方案(x, false, value)).ToList();
                                原方案.Dispose(false);
                            }
                            else
                                原方案.Dispose(true);
                            value.父 = new(原方案.父);

                            原方案.Dispose(true);
                            数据库.方案[index] = value;
                            value.Set节点数据(index, key, out 节点);
                            方案列表.Items[index] = 节点;
                        }
                    }
                    else
                    {
                        key.子.Add(value);
                        value.父.Add(key);
                        value.Set节点数据(key.子.Count - 1, key, out 节点);
                        ((TreeViewItem)方案列表?.SelectedItem)?.Items.Add(节点);
                    }
                }
                数据库.当前方案 = value;
                方案列表数据[value] = 节点;
                UI刷新.方案列表Add(节点, value.子);
                节点.IsSelected = true;
            }
            public bool Replace(_步骤 value)
            {
                if (方案为空() || 数据库.当前方案 == null)
                    return false;

                TreeViewItem 节点;

                int index = -1;
                if (数据库.当前步骤 != null)
                    index = 数据库.当前方案.步骤.IndexOf(数据库.当前步骤);
                if (index > -1)
                {
                    数据库.当前方案.步骤[index].Dispose(true);
                    数据库.当前方案.步骤[index] = value;
                    value.Set节点数据(index, null, out 节点);
                    MainWindow.This.步骤列表.Items[index] = 节点;
                    步骤列表数据[value] = 节点;
                }
                else
                {
                    数据库.当前方案.步骤.Add(value);
                    value.Set节点数据(数据库.当前方案.步骤.Count - 1, null, out 节点);
                    MainWindow.This.步骤列表.Items.Add(节点);
                    步骤列表数据[value] = 节点;
                }
                index = 1;
                foreach (TreeViewItem item in MainWindow.This.步骤列表.Items)
                {
                    string bzName = 数据库.当前方案.步骤[index - 1].名字;
                    if (bzName != null)
                        item.Header = bzName + index++;
                    else
                        item.Header = "步骤" + index++;
                }

                节点.IsSelected = true;
                return true;
            }


        }



        /// <summary>
        /// 节点.绑定(方法, "选中", TreeViewItem.IsSelectedProperty);  
        /// </summary>
        public static (T 对象, int 索引, T 父) Get节点数据<T>(this TreeViewItem 节点) where T : I数据库 => ((T 对象, int 索引, T 父))节点.Tag;
        public static (T 对象, int 索引, T 父) Get节点数据<T>(this TreeView 节点) where T : I数据库 => ((T 对象, int 索引, T 父))((TreeViewItem)节点.SelectedItem).Tag;
        public static void Set节点数据<T>(this T 对象, int 索引, T 父, out TreeViewItem 节点) where T : I数据库
        {
            节点 = new();
            if (对象 is _方法 x)
                节点.Header = x.名字;
            else if (对象 is _步骤 j)
                节点.Header = j.名字;
            else if (对象 is _方案 y)
                节点.Header = y.名字;
            else
                throw new Exception("对象不存在");
            节点.Tag = (对象, 索引, 父);
        }
        public static void Reise节点数据<T>(this T 对象, int 索引, T 父, ref TreeViewItem 节点) where T : I数据库
        {
            if (对象 is _方法 x)
                节点.Header = x.名字;
            else if (对象 is _步骤 j)
                节点.Header = j.名字;
            else if (对象 is _方案 y)
                节点.Header = y.名字;
            else
                throw new Exception("对象不存在");
            节点.Tag = (对象, 索引, 父);
        }
        public static _数据库 读档(bool 删除最新文件 = false)
        {
            string 路径 = "数据库";
            if (!File.Exists(路径))
                System.IO.Directory.CreateDirectory(路径);

            DirectoryInfo di = new(路径);
            FileInfo[] files = di.GetFiles();

            FileInfo 最新文件 = files.OrderByDescending(f => f.LastWriteTime).FirstOrDefault();

            if (最新文件 != null)
            {
                if (删除最新文件)
                {
                    最新文件.Delete();
                    MoyuDelay.Star(100);
                    最新文件 = files.OrderByDescending(f => f.LastWriteTime).FirstOrDefault();
                }

                Debug.WriteLine("最新的文件是：" + 最新文件.Name);
                byte[] data = File.ReadAllBytes($".\\数据库\\{最新文件.Name}");
                using (MemoryStream ms = new MemoryStream(data))
                {
                    using (BsonReader reader = new BsonReader(ms))
                    {
                        return serializer.Deserialize<_数据库>(reader);
                    }
                }
            }
            else
            {
                Debug.WriteLine("文件夹中没有文件");
                return new _数据库();
            }
        }

        public static OneThread 单行_存档锁 = new();
        public static void 存档()
        {
            MoyuThreadPool.Post(() =>
            {
                if (单行_存档锁.Wait(10000))
                {
                    try
                    {
                        数据库 = 数据库.版本检查(false);
                        string 文件名 = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss.fff");

                        using (MemoryStream ms = new MemoryStream())
                        {
                            using (BsonWriter writer = new(ms))
                                serializer.Serialize(writer, 数据库);
                            File.WriteAllBytes($".\\数据库\\{文件名}.bson", ms.ToArray());
                        }
                        清理存档();
                        Thread.Sleep(5000);
                    }
                    catch
                    { throw; }
                    finally
                    {
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                    }
                }
            });
        }

        private static void 清理存档()
        {
            string 目录 = Directory.GetCurrentDirectory() + "\\数据库";
            var files = Directory.GetFiles(目录).OrderByDescending(f => new FileInfo(f).LastWriteTime).ToList();

            if (files.Count > 10)
            {
                var filesToDelete = files.Skip(10).ToList();
                foreach (var file in filesToDelete)
                {
                    File.Delete(file);
                }
            }
        }

        public static void 空(object sender, EventArgs e) { }
        public static void 空() { }
        public static ConcurrentDictionary<DateTime, _屏蔽区域> 屏蔽区域 = new();
        public class _屏蔽区域
        {
            public System.Drawing.Rectangle 区域;
            public int 屏蔽时长;
            public bool 屏蔽完成;
        }


        public static bool 方案为空()
        { return (数据库?.方案?.Count ?? 0) == 0; }
        public static bool 步骤为空()
        {
            return (数据库?.当前方案?.步骤?.Count ?? 0) == 0;
        }
        public static bool 方法为空()
        {
            return (数据库?.当前步骤?.方法?.Count ?? 0) == 0;
        }
        public static bool 方法参数为空()
        {
            return (数据库?.当前方法?.参数?.Count ?? 0) == 0;
        }

        public static string 文本值合并(this _参数 参数)
        {
            string 文本 = string.Format(参数.解释, 参数.值);
            return 文本;
        }

        public static bool 有图(this RichTextBox rich)
        {
            List<Image> images = new();
            FlowDocument document = rich.Document;
            if (document != null)
            {
                foreach (Block block in document.Blocks)
                {
                    if (block is Paragraph paragraph)
                    {
                        foreach (Inline inline in paragraph.Inlines)
                        {
                            if (inline is InlineUIContainer container && container.Child is Image image)
                            {
                                images.Add(image);
                                return true;
                            }
                        }
                    }
                    // 如果还有其他类型的Block，可以根据需要进行处理  
                }
            }
            else
                return false;
            return images.Count > 0;
        }
        public static List<MoyuBitmap> 图片(this RichTextBox rich)
        {
            // 获取RichTextBox中的所有图片  
            List<BitmapSource> images = new();

            FlowDocument document = rich.Document;
            if (document != null)
            {
                foreach (Block block in document.Blocks)
                {
                    if (block is Paragraph paragraph)
                    {
                        foreach (Inline inline in paragraph.Inlines)
                        {
                            if (inline is InlineUIContainer container && container.Child is Image image)
                            {
                                images.Add((BitmapSource)image.Source);
                            }
                        }
                    }
                    // 如果还有其他类型的Block，可以根据需要进行处理  
                }
            }
            return images.Select(b => new MoyuBitmap(b)).ToList();
        }



        public static class 在监听参数
        {
            public static bool _失去焦点;
            public static bool 失去焦点
            {
                get
                {
                    return _失去焦点;
                }
                set
                {
                    if (!_失去焦点)
                    {
                        键鼠.钩子.键盘Click -= MainWindow.This.参数按键监听;
                    }
                    _失去焦点 = value;
                }
            }
            public static TreeViewItem 节点;
            public static _数据库._参数 参数;
            public static string 参数字符串;
            public static void 快捷键赋值(IEnumerable<int> 按键s)
            {
                Dictionary<Keys, DateTime> newkeys = new();
                foreach (var k in 按键s)
                    newkeys.Add((Keys)k, default);
                switch (参数字符串)
                {
                    case "开始快捷键":
                        数据库.开始快捷键 = newkeys;
                        break;
                    case "结束快捷键":
                        数据库.结束快捷键 = newkeys;
                        break;
                    case "截图快捷键":
                        数据库.截图快捷键 = newkeys;
                        break;
                    case "隐藏快捷键":
                        数据库.隐藏快捷键 = newkeys;
                        break;
                    case "注册的按键":
                        break;
                    default:
                        break;
                }
            }
            public static string 按键值合并(IEnumerable<int> 键) { return string.Join("+", 键.Select(p => p.ToString())); }
            public static string 按键值合并(IEnumerable<Keys> 键) { return string.Join("+", 键.Select(p => p.ToString())); }
        }

        public static void 选中新变量()
        {
            数据库.当前变量 = (string?)((TreeViewItem)MainWindow.This.变量列表.SelectedItem).Header;
        }


        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static int EF(this int x)
        {
            return 1 << x;
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static double 幂(this int x, int y) { return Math.Pow(x, y); }

        public static string 取出文本(this RichTextBox richtxtbox)
        {
            TextRange textRange = new TextRange(richtxtbox.Document.ContentStart, richtxtbox.Document.ContentEnd);
            StringBuilder stringBuilder = new(textRange.Text);
            int leng = stringBuilder.Length - 1;
            if (leng > 0)
            {
                char str = new();
                for (int i = leng; i >= leng - 1; i--)
                {
                    str = stringBuilder[i];
                    if (str == '\n' || str == '\r')
                    {
                        stringBuilder.Remove(i, 1);
                        str = new();
                    }
                }
            }
            return stringBuilder.ToString();
        }
        public static void 替换文本(this RichTextBox richtxtbox, string txt)
        {
            Paragraph para = new Paragraph();
            para.Inlines.Add(new Run(txt));
            richtxtbox.Document.Blocks.Clear();
            richtxtbox.Document.Blocks.Add(para);
        }
        public static void 添加文本(this RichTextBox richTextBox, string txt, bool 换行 = true)
        {
            if (换行)
            {
                Paragraph para = new Paragraph();
                para.Inlines.Add(new Run(txt));
                richTextBox.Document.Blocks.Add(para);
            }
            else
            {
                FlowDocument document = richTextBox.Document;
                if (document == null)
                {
                    document = new FlowDocument();
                    richTextBox.Document = document;
                }

                // 检查文档是否为空或最后一个Block是否是Paragraph  
                if (document.Blocks.Count == 0 || !(document.Blocks.LastBlock is Paragraph paragraph))
                {
                    // 如果没有Paragraph，则创建一个并添加文本  
                    paragraph = new Paragraph();
                    document.Blocks.Add(paragraph);
                }
                // 添加文本到Paragraph的Inlines集合中  
                paragraph.Inlines.Add(new Run(txt));
            }
        }
        public static void 插入文本(this RichTextBox richTextBox, string text)
        {
            var 剪切板原始内容 = System.Windows.Clipboard.GetDataObject();
            System.Windows.Clipboard.SetText(text);
            richTextBox.Paste();
            System.Windows.Clipboard.SetDataObject(剪切板原始内容);
        }
        public static void 插入文本(this System.Windows.Controls.TextBox textBox, string text)
        {
            var 剪切板原始内容 = System.Windows.Clipboard.GetDataObject();
            System.Windows.Clipboard.SetText(text);
            textBox.Paste();
            System.Windows.Clipboard.SetDataObject(剪切板原始内容);
        }

        public static void 添加图片(this RichTextBox richtxtbox, MoyuBitmap bitmap)
        {
            //Image image = new();
            //image.Source = bitmap.BitmapSource;
            ////new InlineUIContainer(image, MainWindow.实例.数据输入框.Selection.Start);

            //Paragraph p = new Paragraph();
            //InlineUIContainer inline = new InlineUIContainer(image);
            //p.Inlines.Add(inline);
            //richtxtbox.Document.Blocks.Add(p);


            Image img = new Image() { Source = bitmap.BitmapSource };
            //img.Height = 50;
            //img.Stretch = Stretch.Uniform;  //图片缩放模式
            new InlineUIContainer(img, richtxtbox.Selection.Start); //插入图片到选定位置
        }
        public static void 覆盖图片(this RichTextBox richtxtbox, List<MoyuBitmap> bitmap)
        {
            richtxtbox.Document.Blocks.Clear();
            for (int i = 0; i < bitmap.Count; i++)
            {
                Image image = new();
                image.Source = bitmap[i].BitmapSource;
                new InlineUIContainer(image, MainWindow.This.数据输入框.Selection.Start);
            }
        }
        public static void 擦除(this RichTextBox richtxtbox)
        { richtxtbox.Document.Blocks.Clear(); }

        public static SolidColorBrush RGB(byte R, byte G, byte B)
        {
            return new SolidColorBrush(Color.FromArgb(255, R, G, B));
        }
        public static Color DrawingColor转Media(System.Drawing.Color color)
        {
            return Color.FromArgb(color.A, color.R, color.G, color.B);
        }


        public static T 鼠下控件<T>() where T : UIElement => FindVisualParent<T>((UIElement)Mouse.DirectlyOver, false);
        public static T 上寻控件<T>(this UIElement 子控件) where T : UIElement => FindVisualParent<T>(子控件, true);
        private static T FindVisualParent<T>(UIElement element, bool 跳过当前控件) where T : UIElement
        {
            UIElement parent = element;
            if (跳过当前控件)
                while (parent != null)
                {
                    parent = VisualTreeHelper.GetParent(parent) as UIElement;
                    var correctlyTyped = parent as T;
                    if (correctlyTyped != null)
                        return correctlyTyped;
                }
            else
                while (parent != null)
                {
                    var correctlyTyped = parent as T;
                    if (correctlyTyped != null)
                        return correctlyTyped;
                    parent = VisualTreeHelper.GetParent(parent) as UIElement;
                }
            return null;
        }
        public static void 下寻子项(_方法 父, Moyuptr<_方法> ptr, int 深度, int 计数 = 0)
        {
            ptr.Value = 父?.子?.FirstOrDefault();
            if (ptr.Value != null && 计数 < 深度)
                下寻子项(ptr.Value, ptr, 深度, ++计数);
            else
                ptr.Value = 父;
        }

        public static IEnumerable<float> Select(this System.Drawing.Point point, Func<float, float> func)
        {
            List<float> result = [func(point.X), func(point.Y)];
            return result;
        }


        public static class imageType
        {
            public struct _mat;
            public static _mat Mat => new();
            public struct _bitmap;
            public static _bitmap Bitmap => new();
            public struct _bitmapsource;
            public static _bitmapsource BitmapSource => new();
        }
        public static class valueType
        {
            public struct _int;
            public static _int Int => new();
            public struct _float;
            public static _float Float => new();
            public struct _double;
            public static _double Double => new();
            public struct _long;
            public static _long Long => new();
            public struct _bool;
            public static _bool Bool => new();
            public struct _string;
            public static _string String => new();
            public struct _byte;
            public static _byte Byte => new();
        }

        public class Win32
        {
            // 窗口扩展样式常量
            public const int WS_EX_LAYERED = 0x00080000;
            public const int WS_EX_TRANSPARENT = 0x00000020;
            // 分层窗口属性常量
            public const int LWA_COLORKEY = 0x00000001;
            public const int 鼠标滚轮 = 0x0800;
            private const int HWND_TOPMOST = -1;
            private const uint SWP_NOMOVE = 0x2;
            private const uint SWP_NOSIZE = 0x1;
            private const uint SWP_SHOWWINDOW = 0x40;
            private const uint LWA_ALPHA = 0x2;
            // 鼠标加速相关
            private const uint SPI_GETMOUSE = 0x0003;
            private const uint SPI_SETMOUSE = 0x0004;
            private const uint SPIF_UPDATEINIFILE = 0x01;
            private const uint SPIF_SENDCHANGE = 0x02;
            public const int WS_EX_NOACTIVATE = 134217728;
            public const int GWL_EXSTYLE = -20;
            [DllImport("user32.dll")]
            public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, string lpszClass, string lpszWindow);
            [DllImport("user32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool IsWindow(IntPtr hWnd);
            public static uint 扫描码get(Keys key) => MapVirtualKey((uint)key, MAPVK_VK_TO_VSC);
            [DllImport("user32.dll")]
            static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref uint pvParam, uint fWinIni);
            /// <summary>  
            /// 前台按键  
            /// </summary>  
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, IntPtr dwExtraInfo);
            /// <summary>  
            /// 后台按键  
            /// </summary>  
            [SuppressUnmanagedCodeSecurity()]
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern bool PostMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);

            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern bool SendMessage(IntPtr hWnd, uint wMsg, uint wParam, uint lParam);

            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern bool SendNotifyMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);
            [SuppressUnmanagedCodeSecurity()]
            [DllImport("user32.dll", SetLastError = true)]
            public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, uint wParam, uint lParam, uint fuFlags, uint uTimeout, out IntPtr lpdwResult);
            //SendMessageTimeout 标志位 
            public const uint 同步执行 = 0x0001 | 0x0002;  // 阻塞调用，如果目标无响应则中止  
            public const uint 异步执行 = 0x0000;
            public const uint 等待完成或出错 = 0x0008;

            // 定义 MapVirtualKey 的映射类型常量  
            public const uint MAPVK_VK_TO_VSC = 0x04; // 将虚拟键码转换为扫描码
            /// <summary>  
            /// 获取虚拟按键的扫描码 
            /// </summary>  
            [DllImport("user32.dll")]
            public static extern uint MapVirtualKey(uint uCode, uint uMapType);
            [DllImport("kernel32.dll")]
            public static extern uint GetCurrentThreadId();
            [DllImport("user32.dll", SetLastError = true)]
            public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
            [DllImport("user32.dll")]
            public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId);
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool SetForegroundWindow(IntPtr hWnd);
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern IntPtr SetFocus(IntPtr hWnd);
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
            public const int MOUSEEVENTF_MOVE = 0x0001;
            [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod")]
            public static extern uint MM_BeginPeriod(uint uMilliseconds);
            [DllImport("winmm.dll", EntryPoint = "timeEndPeriod")]
            public static extern uint MM_EndPeriod(uint uMilliseconds);
            [DllImport("user32.dll")]
            public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, UInt32 nFlags);
            [DllImport("dwmapi.dll")]
            public static extern int DwmRegisterThumbnail(IntPtr dest, IntPtr src, out IntPtr thumb);
            [DllImport("dwmapi.dll")]
            public static extern int DwmUnregisterThumbnail(IntPtr thumb);
            [DllImport("dwmapi.dll")]
            public static extern int DwmQueryThumbnailSourceSize(IntPtr thumb, out PSIZE size);
            [DllImport("dwmapi.dll")]
            public static extern int DwmUpdateThumbnailProperties(IntPtr hThumb, ref DWM_THUMBNAIL_PROPERTIES props);
            [DllImport("user32.dll")]
            public static extern bool GetClientRect(IntPtr hWnd, out Rectangle lpRect);
            [DllImport("user32.dll")]
            public static extern IntPtr GetForegroundWindow();
            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
            [DllImport("user32.dll")]
            public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
            [DllImport("user32.dll")]
            public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, uint crKey, byte bAlpha, uint dwFlags);
            [DllImport("user32.dll")]
            public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
            [DllImport("user32.dll")]
            public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
            private const int SW_HIDE = 0;
            [DllImport("user32.dll")]
            public static extern IntPtr WindowFromPoint(int xPoint, int yPoint);
            [DllImport("user32.dll", SetLastError = true)]
            public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
            [DllImport("user32.dll")]
            public static extern int GetWindowLong(IntPtr hwnd, int nIndex);
            [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
            public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
            [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
            public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
            [DllImport("user32.dll", SetLastError = true)]
            public static extern bool GetWindowRect(IntPtr hWnd, out Win32.RECT lpRect);
            public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam);
            [DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)]
            public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam);
            [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
            public static extern IntPtr GetParent(IntPtr hWnd);
            [DllImport("kernel32.dll", EntryPoint = "SetLastError")]
            public static extern void SetLastError(uint dwErrCode);
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
                int nHeight);
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
            [DllImport("gdi32.dll")]
            public static extern bool DeleteDC(IntPtr hDC);
            [DllImport("gdi32.dll")]
            public static extern bool DeleteObject(IntPtr hObject);
            [DllImport("gdi32.dll")]
            public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
            [DllImport("user32.dll")]
            public static extern IntPtr GetDesktopWindow();
            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowDC(IntPtr hWnd);
            [DllImport("user32.dll")]
            public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rectangle rect);
            public const int SRCCOPY = 0x00CC0020;
            [DllImport("User32.dll", CharSet = CharSet.Auto)]
            internal static extern int GetWindowThreadProcessId(IntPtr hWnd, out IntPtr lpdwProcessId);
            [DllImport("User32.dll", CharSet = CharSet.Auto)]
            internal static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
            [DllImport("User32.dll", CharSet = CharSet.Auto)]
            internal static extern bool IsWindowVisible(IntPtr hWnd);
            internal const uint GW_OWNER = 4;

            private static uint[] mouseParams = new uint[3];
            private static bool 加速已禁用 = false;
            private static uint[] 原始鼠标设置 = new uint[3];

            public static void 禁用鼠标加速()
            {
                // 获取当前鼠标设置
                if (SystemParametersInfo(SPI_GETMOUSE, 0, ref mouseParams[0], 0))
                {
                    // 保存原始设置以便恢复
                    原始鼠标设置[0] = mouseParams[0];
                    原始鼠标设置[1] = mouseParams[1];
                    原始鼠标设置[2] = mouseParams[2];

                    // 检查是否已经启用了鼠标加速 (mouseParams[2] != 0 表示加速已启用)
                    if (mouseParams[2] != 0)
                    {
                        Console.WriteLine($"检测到鼠标加速已启用，当前加速级别: {mouseParams[2]}，正在禁用...");

                        // 禁用鼠标加速：设置加速参数为0
                        uint[] 新设置 = new uint[3];
                        新设置[0] = mouseParams[0]; // 保持其他参数不变
                        新设置[1] = mouseParams[1]; // 保持其他参数不变
                        新设置[2] = 0; // 关闭加速

                        if (SystemParametersInfo(SPI_SETMOUSE, 0, ref 新设置[0], SPIF_UPDATEINIFILE | SPIF_SENDCHANGE))
                        {
                            加速已禁用 = true;
                            Console.WriteLine("鼠标加速已成功禁用");
                        }
                        else
                            Console.WriteLine("禁用鼠标加速失败");
                    }
                    else
                        Console.WriteLine("鼠标加速已经处于禁用状态，无需操作");
                }
                else
                    Console.WriteLine("获取鼠标设置失败");
            }
            public static void 启用鼠标加速()
            {
                // 只有在我们之前禁用了加速的情况下才恢复
                if (加速已禁用)
                {
                    Console.WriteLine("正在恢复原始鼠标加速设置...");

                    if (SystemParametersInfo(SPI_SETMOUSE, 0, ref 原始鼠标设置[0], SPIF_UPDATEINIFILE | SPIF_SENDCHANGE))
                    {
                        加速已禁用 = false;
                        Console.WriteLine($"鼠标加速设置已恢复，加速级别: {原始鼠标设置[2]}");
                    }
                    else
                        Console.WriteLine("恢复鼠标加速设置失败");
                }
                else
                    Console.WriteLine("无需恢复鼠标加速设置（之前未禁用）");
            }

            public static IntPtr GetHandleWindowMainHandle(IntPtr hWnd)
            {
                MoyuControl.MsgboxThrow(hWnd == IntPtr.Zero, "无法获取活动窗口的句柄");

                uint PID = (uint)IntPtr.Zero;
                GetWindowThreadProcessId(hWnd, ref PID);

                IntPtr MainWindowHandle = IntPtr.Zero;
                EnumWindows(new WNDENUMPROC((hWnd, lParam) =>
                {
                    uint PID = default;
                    GetWindowThreadProcessId(hWnd, ref PID);
                    if (PID == lParam && IsWindowVisible(hWnd) && GetWindow(hWnd, GW_OWNER) == IntPtr.Zero)
                    {
                        MainWindowHandle = hWnd;
                        return false;
                    }
                    return true;
                }), PID);

                return MainWindowHandle;
            }
            public static IntPtr GetActiveWindowMainHandle() => GetHandleWindowMainHandle(GetForegroundWindow());

            #region Interop structs
            public static readonly int DWM_TNP_VISIBLE = 0x8;
            public static readonly int DWM_TNP_OPACITY = 0x4;
            public static readonly int DWM_TNP_RECTDESTINATION = 0x1;
            private static readonly object 前台窗口rect;
            [StructLayout(LayoutKind.Sequential)]
            public struct DWM_THUMBNAIL_PROPERTIES
            {
                public int dwFlags;
                public RECT rcDestination;
                public RECT rcSource;
                public byte opacity;
                public bool fVisible;
                public bool fSourceClientAreaOnly;
            }
            [StructLayout(LayoutKind.Sequential)]
            public struct RECT
            {
                public RECT(int left, int top, int right, int bottom)
                {
                    Left = left;
                    Top = top;
                    Right = right;
                    Bottom = bottom;
                }
                public static RECT Creat(int left, int top, int width, int height)
                {
                    RECT rECT = new();
                    rECT.Left = left;
                    rECT.Top = top;
                    rECT.Right = left + width;
                    rECT.Bottom = top + height;
                    return rECT;
                }
                public RECT() { }
                public int Left;
                public int Top;
                public int Right;
                public int Bottom;

                public System.Drawing.Rectangle ToRectangle()
                {
                    return new System.Drawing.Rectangle(Left, Top, Right - Left, Bottom - Top);
                }
                public System.Drawing.Size ToSize()
                {
                    return new System.Drawing.Size(Right - Left, Bottom - Top);
                }
                public int Width => Right - Left;
                public int Height => Bottom - Top;
            }
            [StructLayout(LayoutKind.Sequential)]
            public struct PSIZE
            {
                public int x;
                public int y;
            }
            [Flags]
            public enum DWM_THUMBNAIL_PROPERTIES_Flags : uint
            {
                RectDestination = 0x00000001,
                RectSource = 0x00000002,
                Opacity = 0x00000004,
                Visible = 0x00000008,
                SourceClientAreaOnly = 0x00000010
            }
            #endregion
            //只能绘制到顶层窗口！而且此窗口的控件无法再互动！
            public static void Creat镜像窗口(IntPtr 源窗口handle, Form 前台窗口, Win32.RECT 要截取的源窗口区域, double 缩放比例, ref IntPtr 位图句柄)
            {
                位图句柄 = IntPtr.Zero;
                try
                {
                    Win32.DwmRegisterThumbnail(前台窗口.Handle, 源窗口handle, out 位图句柄);

                    前台窗口.ClientSize = 要截取的源窗口区域.ToSize();
                    Win32.RECT 绘制到前台窗口的位置和大小 = new(0, 0, (int)Math.Round(要截取的源窗口区域.Width * 缩放比例, 0), (int)Math.Round(要截取的源窗口区域.Height * 缩放比例, 0));
                    Win32.DWM_THUMBNAIL_PROPERTIES props = new Win32.DWM_THUMBNAIL_PROPERTIES
                    {
                        dwFlags = (int)(Win32.DWM_THUMBNAIL_PROPERTIES_Flags.RectDestination |
                               Win32.DWM_THUMBNAIL_PROPERTIES_Flags.Visible |
                               Win32.DWM_THUMBNAIL_PROPERTIES_Flags.Opacity |
                               Win32.DWM_THUMBNAIL_PROPERTIES_Flags.SourceClientAreaOnly |
                            Win32.DWM_THUMBNAIL_PROPERTIES_Flags.RectSource),
                        rcDestination = 绘制到前台窗口的位置和大小,
                        opacity = 255,
                        fVisible = true,
                        rcSource = 要截取的源窗口区域,
                        fSourceClientAreaOnly = false
                    };
                    Win32.DwmUpdateThumbnailProperties(位图句柄, ref props);
                }
                catch (Exception ex)
                {
                    if (位图句柄 != IntPtr.Zero)
                        Win32.DwmUnregisterThumbnail(位图句柄);
                    MoyuControl.MsgboxThrow(true, "错误: " + ex.Message);
                }
            }
            public static void Up镜像窗口(Win32.RECT 要截取的源窗口区域, double 缩放比例, ref IntPtr 位图句柄)
            {
                try
                {
                    Win32.RECT 绘制到前台窗口的位置和大小 = new(0, 0, (int)Math.Round(要截取的源窗口区域.Width * 缩放比例, 0), (int)Math.Round(要截取的源窗口区域.Height * 缩放比例, 0));
                    Win32.DWM_THUMBNAIL_PROPERTIES props = new Win32.DWM_THUMBNAIL_PROPERTIES
                    {
                        dwFlags = (int)(Win32.DWM_THUMBNAIL_PROPERTIES_Flags.RectDestination |
                               Win32.DWM_THUMBNAIL_PROPERTIES_Flags.Visible |
                               Win32.DWM_THUMBNAIL_PROPERTIES_Flags.Opacity |
                               Win32.DWM_THUMBNAIL_PROPERTIES_Flags.SourceClientAreaOnly |
                            Win32.DWM_THUMBNAIL_PROPERTIES_Flags.RectSource),
                        rcDestination = 绘制到前台窗口的位置和大小,
                        opacity = 255,
                        fVisible = true,
                        rcSource = 要截取的源窗口区域,
                        fSourceClientAreaOnly = false
                    };
                    Win32.DwmUpdateThumbnailProperties(位图句柄, ref props);
                }
                catch (Exception ex)
                {
                    if (位图句柄 != IntPtr.Zero)
                        Win32.DwmUnregisterThumbnail(位图句柄);
                    MoyuControl.MsgboxThrow(true, "错误: " + ex.Message);
                }
            }
        }

        public struct SendInputs
        {
            // 定义INPUT结构体
            [StructLayout(LayoutKind.Sequential)]
            public struct INPUT
            {
                public uint type;
                public InputUnion U;
            }

            // 定义InputUnion联合体
            [StructLayout(LayoutKind.Explicit)]
            public struct InputUnion
            {
                [FieldOffset(0)]
                public MOUSEINPUT mi;
                [FieldOffset(0)]
                public KEYBDINPUT ki;
                [FieldOffset(0)]
                public HARDWAREINPUT hi;
            }

            // 定义MOUSEINPUT结构体
            [StructLayout(LayoutKind.Sequential)]
            public struct MOUSEINPUT
            {
                public int dx;
                public int dy;
                public int mouseData;
                public uint dwFlags;
                public int time;
                public IntPtr dwExtraInfo;
            }

            // 定义KEYBDINPUT结构体
            [StructLayout(LayoutKind.Sequential)]
            public struct KEYBDINPUT
            {
                public ushort wVk;
                public ushort wScan;
                public int dwFlags;
                public int time;
                public IntPtr dwExtraInfo;
            }

            // 定义HARDWAREINPUT结构体
            [StructLayout(LayoutKind.Sequential)]
            public struct HARDWAREINPUT
            {
                public int uMsg;
                public short wParamL;
                public short wParamH;
            }
            public const uint INPUT_MOUSE = 0;
            public const int MOUSEEVENTF_MOVE = 0x0001;
            public const int MOUSEEVENTF_ABSOLUTE = 0x8000;
            public const int KEYEVENTF_KEYUP = 0x2;
            public const int KEYEVENTF_KEYDOWN = 0x1;
            public const uint INPUT_KEYBOARD = 1;
            //评价：不如keybd_event，依旧是用户级模拟
            [DllImport("user32.dll", SetLastError = true)]
            public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
            public static INPUT 相对移动(int dx, int dy)
            {
                MOUSEINPUT mi = new MOUSEINPUT();
                mi.mouseData = 0;
                mi.dwFlags = MOUSEEVENTF_MOVE;
                mi.time = 0;
                mi.dwExtraInfo = IntPtr.Zero;
                mi.dx = dx; //如果要改变坐标值, 一定要重新创建结构！
                mi.dy = dy;
                // 创建INPUT结构实例并设置MOUSEINPUT数据  
                INPUT inputs = new INPUT();
                inputs.type = INPUT_MOUSE;
                inputs.U = new InputUnion { mi = mi };
                return inputs;
            }
        }
        /// <summary>
        /// 四舍五入到指定小数位
        /// </summary>
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static unsafe double round(this double x, int F = 0) => Math.Round(x, F);
        /// <summary>
        /// 四舍五入到整数
        /// </summary>
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static unsafe int round(this double x) => (int)Math.Round(x);

        //锁定鼠标键盘
        [DllImport("user32.dll")]
        public static extern void BlockInput(bool block);

        public static void 移除焦点()
        {
            //设置焦点移动方向
            FocusNavigationDirection focusDirection = FocusNavigationDirection.Next;
            TraversalRequest request = new TraversalRequest(focusDirection);
            // 获取具有键盘焦点的元素
            UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;
            // 更改键盘焦点
            if (elementWithFocus != null)
            {
                elementWithFocus.MoveFocus(request);
                Keyboard.ClearFocus();
            }
        }

        public static bool 已注销(this MoyuThreadPool timer)
        {
            return timer != null;
        }


        public static System.Windows.Size GetSize(string 文本, double 字体大小)
        {
#pragma warning disable CS0618 // 类型或成员已过时
            FormattedText formattedText = new(
               文本,
               CultureInfo.CurrentCulture,
            System.Windows.FlowDirection.LeftToRight,
               new Typeface("Microsoft YaHei UI"),
               字体大小 + 1,
               Brushes.Black);
#pragma warning restore CS0618 // 类型或成员已过时
            return new(formattedText.Width, formattedText.Height);
        }


        public class 颜色
        {
            public byte R;
            public byte G;
            public byte B;
            public 颜色(byte r, byte g, byte b)
            {
                R = r;
                G = g;
                B = b;
            }
            public bool 判断(颜色 obj)
            {
                return R == obj.R && G == obj.G && B == obj.B;
            }

            public override int GetHashCode()
            {
                return R.GetHashCode() ^ G.GetHashCode() ^ B.GetHashCode();
            }

            public static bool operator ==(颜色 color1, 颜色 color2)
            {
                return color1.判断(color2);
            }
            public static bool operator !=(颜色 color1, 颜色 color2)
            {
                return !(color1 == color2);
            }
            public static implicit operator 颜色(System.Drawing.Color 值) => new 颜色(值.R, 值.G, 值.B);

            public float 相似度(颜色 color2)
            {
                int Rc = Math.Abs(R - color2.R);
                int Gc = Math.Abs(G - color2.G);
                int Bc = Math.Abs(B - color2.B);
                return (Rc + Gc + Bc) / 765F;
            }
        }

        public static void TryCatch(Action tryaction, Action finallyaction)
        {
            try
            {
                tryaction();
            }
            catch (MoyuException e)
            {
                Debug.WriteLine(e.Message);
                return;
            }
            catch
            {
                throw;
            }
            finally
            {
                finallyaction();
            }
        }
        public static void 返回顶级调用堆栈(string 信息 = "手动结束")
        {
            throw new MoyuException(信息);
        }
        public class MoyuException : Exception
        {
            //创建一个没有错误消息的异常对象
            public MoyuException() { }
            //创建一个包含错误消息的异常对象。
            public MoyuException(string message) : base(message)
            { }
            //创建一个包含错误消息和内部异常对象的异常对象。
            public MoyuException(string message, Exception innerException) : base(message, innerException)
            { }
        }

        public static 颜色 GetPixel(this Mat mat, int x, int y)
        {
            Vec4b pixelValue = mat.At<Vec4b>(y, x);
            byte blue = pixelValue[0];
            byte green = pixelValue[1];
            byte red = pixelValue[2];
            return new(red, green, blue);
        }
        public static Scalar GetScalar(this Mat mat, int x, int y)
        {
            Vec4b pixelValue = mat.At<Vec4b>(y, x);
            byte blue = pixelValue[0];
            byte green = pixelValue[1];
            byte red = pixelValue[2];
            return new Scalar(blue, green, red);
        }
        public static Mat 副本(this Mat mat)
        {
            OpenCvSharp.Rect 截图大小 = new(new OpenCvSharp.Point(0, 0), mat.Size());
            return new Mat(mat, 截图大小);
        }

        public static int Get变量ID(this string 变量名)
        {
            string pattern = @"\d+$";
            Match match = Regex.Match(变量名, pattern);
            if (match.Success)
                return int.Parse(match.Value);
            else
                return -1;
        }
        public static void 检查变量ID去重()
        {
            if (数据库.变量闲ID == null)
                数据库.变量闲ID = new Queue<int>();

            // 收集所有已使用的ID
            HashSet<int> 已使用ID = new HashSet<int>();
            foreach (var item in 数据库.变量.Keys)
            {
                int id = item.Get变量ID();
                if (id >= 0 && id < 10000)
                    已使用ID.Add(id);
            }

            // 重建闲ID队列（0-9999中未被使用的）
            var 所有可能ID = Enumerable.Range(0, 10000);
            var 闲ID列表 = 所有可能ID.Except(已使用ID).OrderBy(id => id).ToList();

            数据库.变量闲ID = new Queue<int>(闲ID列表);
        }

        public class 耗时检测
        {
            private Stopwatch 计时器;
            public 耗时检测(bool 启动 = false)
            {
                计时器 = new();
                if (启动)
                    Start();
            }
            public void Start() { 计时器.Restart(); }
            public void Stop(string 显示文本 = "耗时")
            {
                Debug.WriteLine(显示文本 + 计时器.ElapsedMilliseconds);
            }
        }

        public static unsafe T ReadPtr<T>(this IntPtr ptr)
        {
            return Unsafe.ReadUnaligned<T>((void*)ptr);
        }
        public static unsafe IntPtr ToPtr<T>(this T 数据)
        {
            return GCHandle.Alloc(数据, GCHandleType.Pinned).AddrOfPinnedObject();
        }




        public static unsafe bool TryRemove(this Dictionary<string, _变量> 变量items, string? 变量item)
        {
            数据库.变量闲ID.Enqueue(变量item.Get变量ID());
            return 变量items.Remove(变量item);
        }

        private static MoyuThreadPool 跟踪目标;
        public static MoyuThreadPool 线程跟踪(MoyuThreadPool 初始目标 = default)
        {
            if (跟踪目标 == null && 初始目标 != null)
                跟踪目标 = 初始目标;
            else if (跟踪目标 != null)
            {
                Debug.WriteLine("线程ID = " + Thread.CurrentThread.ManagedThreadId);
                Debugger.Break();
                return 跟踪目标;
            }
            return default;
        }

        public class MoyuBitmap : IDisposable
        {
            [JsonProperty]
            private byte[] bytes { get; init; }
            public int Width { get; init; }
            public int Height { get; init; }
            public System.Drawing.Imaging.PixelFormat PixelFormat { get; init; }

            public void Dispose()
            {
                Array.Clear(bytes);
            }
            public MoyuBitmap() { }
            public MoyuBitmap(MoyuBitmap bitmap)
            {
                Width = bitmap.Width;
                Height = bitmap.Height;
                PixelFormat = bitmap.PixelFormat;
                uint length = (uint)(Width * Height * 4);
                bytes = new byte[length];
                Unsafe.CopyBlock(ref bytes[0], ref bitmap.bytes[0], sizeof(byte) * length);
            }
            public MoyuBitmap(Bitmap bitmap)
            {
                Width = bitmap.Width;
                Height = bitmap.Height;
                PixelFormat = bitmap.PixelFormat;
                System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
                BitmapData bitmapdata = bitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat);
                int length = Math.Abs(bitmapdata.Stride) * bitmap.Height;
                bytes = new byte[length];
                Marshal.Copy(bitmapdata.Scan0, bytes, 0, length);
                bitmap.UnlockBits(bitmapdata);
            }
            public unsafe MoyuBitmap(Mat mat)
            {
                Width = mat.Width;
                Height = mat.Height;
                PixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppArgb;
                bytes = new byte[mat.Rows * mat.Cols * 4];
                //Unsafe.CopyBlock(Unsafe.AsPointer(ref bytes[0]), mat.DataPointer, (uint)bytes.Length);
                Marshal.Copy(mat.Data, bytes, 0, bytes.Length);
            }
            public MoyuBitmap(BitmapSource bitmapS)
            {
                Width = bitmapS.PixelWidth;
                Height = bitmapS.PixelHeight;
                PixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppRgb;
                Int32 Stride = Width << 2; // 扫描行跨距
                bytes = new byte[Height * Stride];
                if (bitmapS.Format == PixelFormats.Bgra32)
                    bitmapS.CopyPixels(bytes, Stride, 0);
                else
                {   // 先进行像素格式转换，再拷贝像素数据
                    new FormatConvertedBitmap(bitmapS, PixelFormats.Bgra32, null, 0).CopyPixels(bytes, Stride, 0);
                }
            }
            [JsonIgnore]
            public unsafe Mat Mat
            {
                get
                {
                    var src = new Mat(Height, Width, MatType.CV_8UC4);
                    Unsafe.CopyBlock(src.DataPointer, Unsafe.AsPointer(ref bytes[0]), (uint)bytes.Length);
                    return src;
                }
            }
            [JsonIgnore]
            public BitmapSource BitmapSource
            {
                get
                {
                    BitmapSource img;
                    IntPtr hBitmap;
                    hBitmap = this.Bitmap.GetHbitmap();
                    img = Imaging.CreateBitmapSourceFromHBitmap(
                        hBitmap,
                        IntPtr.Zero,
                        Int32Rect.Empty,
                        BitmapSizeOptions.FromEmptyOptions());
                    return img;
                }
            }
            [JsonIgnore]
            public Bitmap Bitmap
            {
                get
                {
                    Bitmap bitmap = new Bitmap(Width, Height, PixelFormat);
                    BitmapData bitmapData = bitmap.LockBits(
                        new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
                        ImageLockMode.WriteOnly,
                        PixelFormat);
                    IntPtr intPtr = bitmapData.Scan0;
                    System.Runtime.InteropServices.Marshal.Copy(bytes, 0, intPtr, bytes.Length);
                    bitmap.UnlockBits(bitmapData);
                    return bitmap;
                }
            }
        }

        public static bool 检查所有步骤参数(this _数据库 数据)
        {
            return 遍历方案组(数据.方案);

            [SkipLocalsInit]
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
            bool 遍历方案组(List<_方案> 方案items)
            {
                if (方案items == null)
                    return false;
                foreach (var 方案item in 方案items)
                {
                    if (方案item == null || 方案item.步骤 == null)
                        return false;
                    int index = 0;
                    foreach (var 步骤item in 方案item.步骤)
                    {
                        index++;
                        if (步骤item == null)
                            return false;
                        if (步骤item.名字 == null)
                            步骤item.名字 = "步骤";
                        UI刷新.检查步骤参数(步骤item);
                    }
                    if (!遍历方案组(方案item.子))
                        return false;
                }
                return true;
            }
        }
        public static bool 检查所有方法参数(this _数据库 数据)
        {
            return 遍历方案组(数据.方案);

            [SkipLocalsInit]
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
            bool 遍历方案组(List<_方案> 方案items)
            {
                if (方案items == null)
                    return false;
                foreach (var 方案item in 方案items)
                {
                    if (方案item == null || 方案item.步骤 == null)
                        return false;
                    foreach (var 步骤item in 方案item.步骤)
                    {
                        if (步骤item == null)
                            return false;
                        if (!遍历方法组(步骤item.方法, default))
                            return false;
                    }
                    if (!遍历方案组(方案item.子))
                        return false;
                }
                return true;
            }
            [SkipLocalsInit]
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
            bool 遍历方法组(List<_方法> 方法items, _方法 父)
            {
                if (方法items == null)
                    return false;
                foreach (var 方法item in 方法items)
                {
                    if (方法item == null)
                        return false;
                    if (父 != null)
                    {
                        方法item.父.Clear();
                        方法item.父.Add(父);
                    }
                    if (方法修改列表.TryGetValue(方法item.名字, out var newName))
                        方法item.名字 = newName;
                    UI刷新.检查方法参数(方法item);
                    if (!遍历方法组(方法item.子, 方法item))
                        return false;
                }
                return true;
            }
        }

        [SkipLocalsInit]
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static double 直线距离(double x1, double x2, double y1, double y2)
        {
            double x = x1 - x2;
            double y = y1 - y2;
            return Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2));
        }
        public static void 进度报告(Moyuptr<double, double, Dictionary<_方法, 核心._数据._方法data>> ptr)
        {
            MainWindow.任务s.Enqueue(() =>
            {
                double 百分比 = ptr.Value2 / ptr.Value1 * 100;
                if (百分比 < 100 && ptr.Value3.Count > 0)
                    MoyuControl.气泡(百分比.ToString("#0.000") + "%", MainWindow.This, 500, () => 进度报告(ptr));
            });
        }

        public static string CloneStr<T>(this T data)
        {
            Newtonsoft.Json.JsonSerializer jsonSer = new()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore //避免无限循环
            };
            using (MemoryStream ms = new MemoryStream())
            {
                using (BsonWriter writer = new BsonWriter(ms))
                {
                    jsonSer.Serialize(writer, data);
                    return Convert.ToBase64String(ms.ToArray());
                }
            }
        }


        [SkipLocalsInit]
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static List<int> ToInt<T>(this Dictionary<Keys, T>.KeyCollection key事件s)
        {
            List<int> values = new();
            foreach (var item in key事件s)
                values.Add((int)item);
            return values;
        }
        [SkipLocalsInit]
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static List<int> ToInt(this List<Keys> key事件s)
        {
            List<int> values = new();
            foreach (var item in key事件s)
                values.Add((int)item);
            return values;
        }

        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static unsafe int round(this float x)
        {
            return int.Parse(x.ToString("#0"));
        }

        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static void Using<T>(T 数据, Action<T> action) where T : IDisposable
        {
            try
            {
                action(数据);
            }
            finally
            {
                MoyuThreadPool.Post(数据.Dispose);
            }
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static void Using<T>(Array 数据, Action<Array> action)
        {
            try
            {
                action(数据);
            }
            finally
            {
                MoyuThreadPool.Post(() => Array.Clear(数据));
            }
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static void Using<T>(T[] 数据, Action<T[]> action) where T : IDisposable
        {
            try
            {
                action(数据);
            }
            finally
            {
                MoyuThreadPool.Post(() =>
                {
                    foreach (var item in 数据)
                        item.Dispose();
                    Array.Clear(数据);
                });
            }
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static void Using<T, K>(K 数据, Action<K> action) where K : IList<T> where T : IDisposable
        {
            try
            {
                action(数据);
            }
            finally
            {
                MoyuThreadPool.Post(() =>
                {
                    foreach (var item in 数据)
                        item.Dispose();
                    数据.Clear();
                });
            }
        }

        /// <summary>
        /// 若返回值等于false，则自旋
        /// </summary>
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static void 自旋(Func<bool> func, int ms = 2)
        {
            while (!func())
                MoyuDelay.Star(ms);
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static void 自旋(ref double oldtime, ref double 等待时长, int ms = 2)
        {
            while ((时间戳 - oldtime) < 等待时长)
                MoyuDelay.Star(ms);
            oldtime = 时间戳;
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static void 自旋(ref bool isSet, int ms = 2)
        {
            while (!isSet)
                MoyuDelay.Star(ms);
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static void 自旋(ref bool isSet, ref double oldtime, ref double 等待时长, int ms = 2)
        {
            while ((!isSet) && (时间戳 - oldtime) < 等待时长)
                MoyuDelay.Star(ms);
            oldtime = 时间戳;
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static byte Tobyte(this string str)
        {
            if (string.IsNullOrEmpty(str)) return 0;
            return byte.TryParse(str, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out byte result)
                ? result : (byte)0;
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static int Toint(this string str)
        {
            if (string.IsNullOrEmpty(str)) return 0;
            return int.TryParse(str, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out int result)
                ? result : 0;
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static double Todouble(this string str)
        {
            if (string.IsNullOrEmpty(str)) return 0d;
            return double.TryParse(str, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out double result)
                ? result : 0d;
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static long Tolong(this string str)
        {
            if (string.IsNullOrEmpty(str)) return 0L;
            return long.TryParse(str, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out long result)
                ? result : 0L;
        }
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static float Tofloat(this string str)
        {
            if (string.IsNullOrEmpty(str)) return 0f;
            return float.TryParse(str, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out float result)
                ? result : 0f;
        }

        public static void Binding(this TreeView treeView, IEnumerable 数据s, string 元素子项)
        {
            DataTemplate dataTemplate = new DataTemplate();
            dataTemplate.VisualTree = new FrameworkElementFactory(typeof(TextBlock));
            dataTemplate.VisualTree.SetBinding(TextBlock.TextProperty, new System.Windows.Data.Binding(元素子项));
            treeView.ItemTemplate = dataTemplate;
            treeView.ItemsSource = 数据s;
        }
        public static void Binding(this TreeView treeView, IEnumerable 数据s, string 元素子集, string 元素子项)
        {
            HierarchicalDataTemplate hierarchicalDataTemplate = new HierarchicalDataTemplate();
            hierarchicalDataTemplate.ItemsSource = new System.Windows.Data.Binding(元素子集);
            hierarchicalDataTemplate.VisualTree = new FrameworkElementFactory(typeof(TextBlock));
            hierarchicalDataTemplate.VisualTree.SetBinding(TextBlock.TextProperty, new System.Windows.Data.Binding(元素子项));
            treeView.ItemTemplate = hierarchicalDataTemplate;
            treeView.ItemsSource = 数据s;
        }























    }

    public class ConcurrentHashSet<T> : IEnumerable<T>
    {
        protected volatile SharpCompress.ReadOnlyCollection<T> items;
        protected object writeLock = new object();
        public int Count => items.Count;
        public ConcurrentHashSet()
        {
            this.items = new SharpCompress.ReadOnlyCollection<T>(new HashSet<T>());
        }
        public ConcurrentHashSet(ICollection<T> items)
        {
            this.items = new SharpCompress.ReadOnlyCollection<T>(items);
        }
        public HashSet<T> GetHashSet() => new HashSet<T>(items);
        public void Clear()
        {
            lock (writeLock)
                this.items = new SharpCompress.ReadOnlyCollection<T>(new HashSet<T>());
        }
        public bool Add(T item)
        {
            lock (writeLock)
            {
                HashSet<T> newList = GetHashSet();
                bool removed = newList.Add(item);
                if (!removed)
                    return false;
                this.items = new SharpCompress.ReadOnlyCollection<T>(newList);
            }
            return true;
        }
        public bool Remove(T item)
        {
            lock (writeLock)
            {
                HashSet<T> newList = GetHashSet();
                bool removed = newList.Remove(item);
                if (!removed)
                    return false;
                this.items = new SharpCompress.ReadOnlyCollection<T>(newList);
            }
            return true;
        }
        public bool Contains(T item)
        {
            lock (writeLock)
                return this.items.Contains(item);
        }
        public IEnumerator<T> GetEnumerator()
        {
            lock (writeLock)
                return items.GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            lock (writeLock)
                return ((IEnumerable)items).GetEnumerator();
        }
    }
    public class ConcurrentLinkedHashSet<T> : IEnumerable<T> where T : notnull
    {
        protected volatile SharpCompress.ReadOnlyCollection<T> items;
        protected object writeLock = new object();
        public int Count => items.Count;
        public ConcurrentLinkedHashSet()
        {
            this.items = new SharpCompress.ReadOnlyCollection<T>(new HashSet<T>());
        }
        public ConcurrentLinkedHashSet(ICollection<T> items)
        {
            this.items = new SharpCompress.ReadOnlyCollection<T>(items);
        }
        public LinkedHashSet<T> GetHashSet() => new LinkedHashSet<T>(items);
        public void Clear()
        {
            lock (writeLock)
                this.items = new SharpCompress.ReadOnlyCollection<T>(new HashSet<T>());
        }
        [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
        public bool Add(T item)
        {
            lock (writeLock)
            {
                LinkedHashSet<T> newList = GetHashSet();
                if (!newList.Add(item))
                    return false;
                this.items = new SharpCompress.ReadOnlyCollection<T>(newList);
            }
            return true;
        }
        [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
        public bool Remove(T item)
        {
            lock (writeLock)
            {
                LinkedHashSet<T> newList = GetHashSet();
                if (!newList.Remove(item))
                    return false;
                this.items = new SharpCompress.ReadOnlyCollection<T>(newList);
            }
            return true;
        }
        public bool Contains(T item)
        {
            lock (writeLock)
                return this.items.Contains(item);
        }
        public IEnumerator<T> GetEnumerator()
        {
            lock (writeLock)
                return items.GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            lock (writeLock)
                return ((IEnumerable)items).GetEnumerator();
        }
    }
    public class ConcurrentList<T> : IEnumerable<T>
    {
        [CLSCompliant(false)]
        protected volatile System.Collections.ObjectModel.ReadOnlyCollection<T> items;
        protected object writeLock = new object();
        public int Count => items.Count;

        public ConcurrentList()
        {
            lock (writeLock)
                items = new System.Collections.ObjectModel.ReadOnlyCollection<T>(new List<T>());
        }

        public ConcurrentList(IEnumerable<T> items)
        {
            lock (writeLock)
                this.items = new System.Collections.ObjectModel.ReadOnlyCollection<T>(new List<T>(items));
        }

        public System.Collections.ObjectModel.ReadOnlyCollection<T> GetCollection()
        {
            lock (writeLock)
                return items;
        }

        public IList<T> GetList()
        {
            lock (writeLock)
                return new List<T>(items);
        }
        public T[] GetArray()
        {
            lock (writeLock)
                return items.ToArray();
        }
        public void SetList(IEnumerable<T> list)
        {
            lock (writeLock)
                this.items = new System.Collections.ObjectModel.ReadOnlyCollection<T>(new List<T>(list));
        }
        public void Add(T item)
        {
            lock (writeLock)
            {
                IList<T> newList = GetList();
                newList.Add(item);
                this.items = new System.Collections.ObjectModel.ReadOnlyCollection<T>(newList);
            }
        }
        public void RemoveWhere(Func<T, bool> func)
        {
            lock (writeLock)
            {
                Span<T> span = GetArray();
                for (int i = 0, leng = span.Length; i < leng; i++)
                {
                    if (func(span[i]))
                    {
                        span.RemoveAt(i);
                        break;
                    }
                }
                this.items = new System.Collections.ObjectModel.ReadOnlyCollection<T>(span.ToArray());
            }
        }
        public T this[int index]
        {
            get
            {
                lock (writeLock)
                    return items[index];
            }
            set
            {
                lock (writeLock)
                {
                    IList<T> newList = GetList();
                    newList[index] = value;
                    this.items = new System.Collections.ObjectModel.ReadOnlyCollection<T>(newList);
                }
            }
        }

        public bool Remove(T item)
        {
            lock (writeLock)
            {
                IList<T> newList = GetList();
                bool removed = newList.Remove(item);
                if (!removed) return false; //The item didn't exist, don't fire changed events.
                this.items = new System.Collections.ObjectModel.ReadOnlyCollection<T>(newList);
            }
            return true;
        }
        public void RemoveAt(int index)
        {
            lock (writeLock)
            {
                IList<T> newList = GetList();
                if (index < newList.Count)
                    newList.RemoveAt(index);
                this.items = new System.Collections.ObjectModel.ReadOnlyCollection<T>(newList);
            }
        }
        public void Clear()
        {
            lock (writeLock)
                this.items = new System.Collections.ObjectModel.ReadOnlyCollection<T>(new List<T>());
        }
        public bool Contains(T item)
        {
            lock (writeLock)
                return this.items.Contains(item);
        }
        public IEnumerable<int> GetEnumerable()
        {
            lock (writeLock)
            {
                List<int> list = new List<int>();
                var newlist = GetList();
                foreach (var item in newlist)
                {
                    if (item is 鼠标按键.Data x)
                        list.Add(x.Keys);
                }
                return (IEnumerable<int>)newlist;
            }
        }
        public IEnumerator<T> GetEnumerator()
        {
            lock (writeLock)
                return items.GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            lock (writeLock)
                return ((IEnumerable)items).GetEnumerator();
        }
    }
}

public enum mouse : int
{
    MOUSEEVENTF_ABSOLUTE = 0x8000, //鼠标位置使用绝对坐标  
    MOUSEEVENTF_HWHEEL = 0x1000, //鼠标水平滚轮滚动  
    MOUSEEVENTF_MOVE = 0x1, //鼠标移动  
    MOUSEEVENTF_MOVE_NOCOALESCE = 0x2000, //鼠标移动，不合并事件  
    MOUSEEVENTF_LEFTDOWN = 0x2, //鼠标左键按下  
    MOUSEEVENTF_LEFTUP = 0x4, //鼠标左键释放  
    MOUSEEVENTF_RIGHTDOWN = 0x8, //鼠标右键按下  
    MOUSEEVENTF_RIGHTUP = 0x10, //鼠标右键释放  
    MOUSEEVENTF_MIDDLEDOWN = 0x20, //鼠标中键按下  
    MOUSEEVENTF_MIDDLEUP = 0x40, //鼠标中键释放  
    MOUSEEVENTF_VIRTUALDESK = 0x4000, //鼠标使用虚拟桌面坐标  
    MOUSEEVENTF_WHEEL = 0x800, //鼠标垂直滚轮滚动  
    MOUSEEVENTF_XDOWN = 0x80, //鼠标X键按下  
    MOUSEEVENTF_XUP = 0x100 //鼠标X键释放  
}
public enum Send : uint
{
    WM_LBUTTONDOWN = 0x201, // 鼠标左键按下  
    WM_LBUTTONUP = 0x202,   // 鼠标左键释放  
    MK_LBUTTON = 0x1,       // 鼠标左键标志  
    WM_RBUTTONDOWN = 0x204, // 鼠标右键按下  
    WM_RBUTTONUP = 0x205,   // 鼠标右键释放  
    MK_RBUTTON = 0x2,       // 鼠标右键标志  
    WM_MOUSEMOVE = 0x200,   // 鼠标位置  
                            // 键盘按键消息类型  
    WM_KEYDOWN = 0x100,     // 键盘按下消息  
    WM_KEYUP = 0x101,       // 键盘释放消息  
    WM_CHAR = 0x102,        // 字符消息，对应键盘上的字符按键  
    WM_SYSKEYDOWN = 0x104,  // 系统键盘按下消息，例如Alt键  
    WM_SYSKEYUP = 0x105,    // 系统键盘释放消息，例如Alt键  
    WM_SETTEXT = 0xC,       // 设置句柄控件的文本    
    WM_SYSCHAR = 0x0106,

    // 键盘按键常量  
    VK_BACK = 0x8,          // 退格键  
    VK_TAB = 0x9,           // Tab键  
    VK_RETURN = 0xD,        // 回车键  
    VK_SHIFT = 0x10,        // Shift键  
    VK_CONTROL = 0x11,      // Control键  
    VK_MENU = 0x12,         // Alt键  
    VK_ESCAPE = 0x1B,       // Esc键  
    VK_SPACE = 0x20,        // 空格键  
    VK_LEFT = 0x25,         // 左箭头键  
    VK_UP = 0x26,           // 上箭头键  
    VK_RIGHT = 0x27,        // 右箭头键  
    VK_DOWN = 0x28,         // 下箭头键  
    VK_DELETE = 0x2E,       // 删除键  
    VK_A = 0x41,            // 字母A键  
    VK_B = 0x42,            // 字母B键  
    VK_C = 0x43,            // 字母C键  
    VK_D = 0x44,            // 字母D键  
    VK_E = 0x45,            // 字母E键  
    VK_F = 0x46,            // 字母F键  
    VK_G = 0x47,            // 字母G键  
    VK_H = 0x48,            // 字母H键  
    VK_I = 0x49,            // 字母I键  
    VK_J = 0x4A,            // 字母J键  
    VK_K = 0x4B,            // 字母K键  
    VK_L = 0x4C,            // 字母L键  
    VK_M = 0x4D,            // 字母M键  
    VK_N = 0x4E,            // 字母N键  
    VK_O = 0x4F,            // 字母O键  
    VK_P = 0x50,            // 字母P键  
    VK_Q = 0x51,            // 字母Q键  
    VK_R = 0x52,            // 字母R键  
    VK_S = 0x53,            // 字母S键  
    VK_T = 0x54,            // 字母T键  
    VK_U = 0x55,            // 字母U键  
    VK_V = 0x56,            // 字母V键  
    VK_W = 0x57,            // 字母W键  
    VK_X = 0x58,            // 字母X键  
    VK_Y = 0x59,            // 字母Y键  
    VK_Z = 0x5A             // 字母Z键  
}
